package com.rpa.server.servicerpaserver.expose.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.rpa.secure.servicerpasecure.common.exception.RpaRegisterException;
import com.rpa.secure.servicerpasecure.common.result.Result;
import com.rpa.server.servicerpaserver.crawler.entity.Active;
import com.rpa.server.servicerpaserver.crawler.entity.Score;
import com.rpa.server.servicerpaserver.crawler.service.ScoreService;
import com.rpa.server.servicerpaserver.expose.dto.ActiveDto;
import com.rpa.server.servicerpaserver.expose.dto.ScoreDto;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @className: ScoreController
 * @author: lzt
 * @date: 2025/2/14 13:57
 * @Version: 1.0
 * @description:
 */
@RestController
@RequestMapping("/api/score")
@Slf4j
@Tag(name = "本系统成绩相关接口", description = "ScoreController")
public class ScoreController {
    @Autowired
    private ScoreService scoreService;

    @PostMapping("/resetScore")
    @Operation(summary = "重置成绩", description = "resetScore")
    public Result<Boolean> resetScore(@RequestBody ScoreDto scoreDto) {
        log.info("重置成绩");
        if (scoreDto == null || StrUtil.hasEmpty(scoreDto.getCourseId(), scoreDto.getResetType(), scoreDto.getClazzId())) {
            throw new RpaRegisterException("未选择课程、班级、初始化类型");
        }
        boolean result = scoreService.resetScore(scoreDto);
        return Result.success(result);
    }

    @PostMapping("/saveScoreList")
    @Operation(summary = "保存成绩", description = "saveScoreList")
    public Result<Boolean> saveScoreList(@RequestBody List<Map> scoreList, @RequestParam String isStart) {
        log.info("保存成绩");
        if (CollUtil.isEmpty(scoreList)) {
            return Result.error("未选择成绩");
        }
        if (!(Objects.equals(isStart, "1")||Objects.equals(isStart, "0"))) {
            return Result.error("参数异常");
        }
        boolean b = true;

        for (Map score : scoreList) {
            LambdaUpdateWrapper<Score> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(Score::getId, MapUtil.getStr(score, "scoreId", ""))
                    .set(Score::getScoreNumber, MapUtil.getStr(score, "scoreNumber", ""))
                    .set(Score::getIsStart, Integer.parseInt(isStart))
                    .set(Score::getStudentNumber,MapUtil.getStr(score,"studentNumber",""));
            if (StrUtil.isNotBlank(MapUtil.getStr(score, "scoreName", ""))) {
                updateWrapper.set(Score::getScoreName,MapUtil.getStr(score, "scoreName", "") );
            }
            if (StrUtil.isNotBlank(MapUtil.getStr(score, "proportion", ""))) {
                updateWrapper.set(Score::getProportion,MapUtil.getStr(score, "proportion", "0") );
            }
            b = scoreService.update(updateWrapper)&&b;
        }
        return Result.success(b);
    }
    @PostMapping("/getScoreList")
    @Operation(summary = "获取成绩", description = "getScoreList")
    public Result<List<Score>> getScoreList(@RequestBody ScoreDto scoreDto) {
        log.info("获取成绩");
        if (scoreDto == null || StrUtil.hasEmpty(scoreDto.getAccountId(), scoreDto.getCourseId(), scoreDto.getClazzId())) {
            throw new RpaRegisterException("未选择课程、班级");
        }

        List<Score> scoreList =scoreService.getScoreList(scoreDto);
        return Result.success(scoreList);
    }

    @PostMapping("/saveScoreDefault")
    @Operation(summary = "保存成绩", description = "saveScoreDefault")
    public Result<Boolean> saveScoreDefault(@RequestBody ScoreDto scoreDto) {
        log.info("保存成绩");
        if (Objects.isNull(scoreDto)) {
            return Result.error("未选择成绩");
        }
        boolean b = scoreService.saveScoreDefault(scoreDto);
       return Result.success(b);
    }

    @PostMapping("/getScoreTotal")
    @Operation(summary = "获取最终成绩", description = "getScoreTotal")
    public Result<List<Map<String, Object>>> getScoreTotal(@RequestBody ScoreDto scoreDto) {
        if (Objects.isNull(scoreDto)){
            return Result.error("参数错误");
        }
        List<Map<String, Object>> scoreTotal = scoreService.getScoreTotal(scoreDto);
        return Result.success(scoreTotal);
    }
    @PostMapping(value = "/export/downloadScoreTotal")
    @Operation(summary = "下载成绩列表", description = "downloadScoreTotal")
    public void downloadScoreTotal(@RequestBody ScoreDto scoreDto, HttpServletResponse response) {
        if (scoreDto == null || scoreDto.getFileName() == null || scoreDto.getFileName().trim().isEmpty()) {
            log.warn("下载请求参数无效: {}", scoreDto);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 400 Bad Request
            return;
        }

        try {
            // 设置 Content-Type 和 Content-Disposition
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            // 文件名的 URL 编码
            String fileName = URLEncoder.encode(scoreDto.getFileName(), "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            List<Map<String, Object>> scoreTotal = scoreService.getScoreTotal(scoreDto);
            // 使用 EasyExcel 写入 Excel 文件流到响应输出流
            EasyExcel.write(response.getOutputStream())
                    .head(scoreService.headTotal(scoreTotal))
                    .sheet(scoreDto.getFileName())
                    .doWrite(scoreService.dataListTotal(scoreTotal));

        } catch (Exception e) {
            log.error("下载成绩列表失败, activeDto: {}", scoreDto, e); // 记录异常
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error
        } finally {
            // 确保关闭输出流
            try {
                response.getOutputStream().close();
            } catch (IOException e) {
                log.error("关闭输出流失败", e);
            }
        }
    }

    @PostMapping(value = "/export/downloadScoreList")
    @Operation(summary = "下载测试列表", description = "downloadScoreList")
    public void downloadScoreList(@RequestBody ScoreDto scoreDto, HttpServletResponse response) {
        if (scoreDto == null || scoreDto.getFileName() == null || scoreDto.getFileName().trim().isEmpty()) {
            log.warn("下载请求参数无效: {}", scoreDto);
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST); // 400 Bad Request
            return;
        }

        try {
            // 设置 Content-Type 和 Content-Disposition
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName1 = Objects.equals(scoreDto.getScoreType(), "1") ? "期末" : "期中";
            // 文件名的 URL 编码
            String fileName = URLEncoder.encode(scoreDto.getFileName() + fileName1, "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            // 使用 EasyExcel 写入 Excel 文件流到响应输出流
            EasyExcel.write(response.getOutputStream())
                    .head(scoreService.head())
                    .sheet(scoreDto.getFileName())
                    .doWrite(scoreService.dataList(scoreDto));

        } catch (Exception e) {
            String fileName1 = Objects.equals(scoreDto.getScoreType(), "1") ? "期末" : "期中";
            log.error("下载{}列表失败, activeDto: {}",fileName1, scoreDto, e); // 记录异常
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 Internal Server Error
        } finally {
            // 确保关闭输出流
            try {
                response.getOutputStream().close();
            } catch (IOException e) {
                log.error("关闭输出流失败", e);
            }
        }
    }
}
